#!/bin/bash
# Copyright (c) 2023-2024 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================

pushd 3rdparty/
sh prepare_oneccl.sh
source ./oneccl/build/_install/env/setvars.sh
popd

current_dir=$(pwd)
workspace_dir=$(echo $current_dir | sed 's|\(.*\/xFasterTransformer\).*|\1|')

source $workspace_dir/ci/test_case

# get commit id & tag name
commit_id=$(git rev-parse HEAD)
tag_name=$(git tag --points-at $commit_hash)
if [ -n "$tag_name" ]; then
    commit_id="$tag_name"
fi

log_dir=$HOME/xft
commit_dir=$HOME/xft/$commit_id
csv_path=$HOME/xft/$commit_id/test_case.csv
svr_log_dir=$HOME/xft/$commit_id/svr_info

if [ ! -d $svr_log_dir ]; then
    mkdir -p $svr_log_dir
fi

git log --pretty=full $commit_id -n 3 &> $commit_dir/commit_info.txt

interrupt_handler() {
    exit 1
}
trap interrupt_handler SIGINT

function Info() {
    echo -e "\033[32m[Info] $@ \033[0m"
}

function Warning() {
    echo -e "\033[33;3m[Warning] $@ \033[0m"
}

function Error() {
    echo -e "\033[31m[Error] $@ \033[0m"
    exit 1
}

svr_info() {
    pushd $log_dir
    if [ ! -d "svr-info" ]; then
        wget -qO- https://github.com/intel/svr-info/releases/latest/download/svr-info.tgz | tar xvz
    fi
    cd svr-info
    ./svr-info -output $svr_log_dir
    popd
}

# Define functions for build, UT, and model
build() {
    pip install -r requirements.txt
    Info "Running build function with arguments: $@"
    rm -rf build && mkdir build && cd build && cmake -DXFT_BUILD_TESTS=ON -DXFT_BUILD_EVALUATION=ON -DPython_EXECUTABLE=$(which python) .. && make -j
}

ut() {
    fail_targets=()
    pushd $workspace_dir/build/ut/
    Info "Running UT function with arguments: $@"
    for file in ./*; do
        if [ -x "$file" ]; then

            if [[ "$file" != *_test ]]; then
                Warning "$file is not ending with '_test', skip current loop."
                continue
            fi
            Info "Running UT: $file"
            ./$file
            if [ $? -ne 0 ]; then
                fail_targets+=("$file")
            fi
            echo
        fi
    done
    popd
    if [ ${#fail_targets[@]} -gt 0 ]; then
        targets_str=""
        for element in "${fail_targets[@]}"; do
            targets_str+=" $element"
        done

        Error "Error: $targets_str execution failed"
    fi
}

model() {
    fail_targets=()
    model_case=()
    while IFS= read -r line; do
        trimmed_line="${line#"${line%%[![:space:]]*}"}"
        if [[ -n "$trimmed_line" && ! "$trimmed_line" =~ ^# ]]; then
            model_case+=("$line")
        fi
    done <<<"$_test_case"

    pushd benchmark/
    for _case in "${model_case[@]}"; do
        Info "Running model function: $_case $@"
        eval $_case $@ --csv $csv_path
        if [ $? -ne 0 ]; then
            Warning "Error: $_case execution failed"
            fail_targets+=("$_case")
        fi
        echo
    done
    popd
    if [ ${#fail_targets[@]} -gt 0 ]; then
        targets_str=""
        for element in "${fail_targets[@]}"; do
            targets_str+="\n --> $element\n"
        done

        Error "Error: $targets_str execution failed"
    fi
}

release() {
    fail_targets=()
    model_case=()
    while IFS= read -r line; do
        trimmed_line="${line#"${line%%[![:space:]]*}"}"
        if [[ -n "$trimmed_line" && ! "$trimmed_line" =~ ^# ]]; then
            model_case+=("$line")
        fi
    done <<<"$rls_test_case"

    pushd benchmark/
    for _case in "${model_case[@]}"; do
        Info "Running model function: $_case $@"
        eval $_case $@ --csv $csv_path
        if [ $? -ne 0 ]; then
            Warning "Error: $_case execution failed"
            fail_targets+=("$_case")
        fi
        echo
    done
    popd
    if [ ${#fail_targets[@]} -gt 0 ]; then
        targets_str=""
        for element in "${fail_targets[@]}"; do
            targets_str+="\n --> $element\n"
        done

        Error "Error: $targets_str execution failed"
    fi
}

# Check if a function with the given name exists and call it with provided arguments
if [ "$#" -ge 1 ]; then
    function_name="$1"
    shift
    if [ "$(type -t $function_name)" = "function" ]; then
        exec &> >(tee ${commit_dir}/output_${function_name}.txt)
        $function_name "$@"
    else
        Error "Function $function_name not found."
    fi
else
    Info "Usage: ci_build function_name [function_arguments...]"
fi
